neutron.setTitle("File Manager")
neutron.setMinSize(420, 340)
neutron.getInfo((data) => {
    if (data[0]["w"] < 420) {
        neutron.setWinSize(600, 400)
    }
});


function htmlEncode(html) {
    var temp = document.createElement("div");
    (temp.textContent != null) ? (temp.textContent = html) : (temp.innerText = html);
    var output = temp.innerHTML;
    temp = null;
    return output;
}
function onscroll(event) { // 地址栏滚动事件
    var delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail)));
    this.scrollLeft -= (delta * 30);
};

var obj_id = 0 // dom id
var file_path = "/" // 当前路径
var file_path_ws_tmp = "" // 路径 websocket 更新检测变量
var search_mode = 0 // 是否为搜索
var show_hides = 0 // 显示隐藏文件
var files_lst = [] // 文件列表
var history_lst = [] // 路径历史
var choose_files = new Set() // 选择的文件，值为index
var multi_choose = false // 启用多选模式（无需ctrl）
var disable_mulit_choose = false // 禁用多选模式
var choose_lock = false // 选择锁定
var create_type = "" // 文件创建类型 Literal["file","dir"]
var create_is_rename = "" // 用于重命名与复制文件的输入框与事件复用
var choosed_file_id = 0 // 复用重命名时选择的文件id
var cutmode = "move" // 剪切复制模式 Literal["move","copy"]
var ws = null // 搜索 websocket
var bookmark_list = [] // 书签列表
var bookmark_last_choice = -1 // 最后选择的书签
var watch_ws = null // 监视 websocket 对象

if (window.parent.NEUTRON_FILEMANAGER_CUTLIST == undefined) {
    window.parent.NEUTRON_FILEMANAGER_CUTLIST = [] // 剪切复制文件列表
}

window.onload = function () {
    bind_all_events()
    init_bookmarks()
    neutron.loadData((loadobjs) => { // 加载路径
        var loadobj = loadobjs[0]
        var url = new URL(window.location.href);
        if (url.searchParams.has("path")) {
            file_path = url.searchParams.get("path")
        }
        if (url.searchParams.has("choose")) { // 选择模式
            if (loadobj != null && neutron.winid < 100000) { // 关闭临时对话框
                neutron.close()
                return
            }
            var choose_callback_mode = url.searchParams.get("choose")
            var choose_callback_winid = url.searchParams.get("choose_callback")
            var choose_callback_userid = url.searchParams.get("choose_callback_id")
            document.getElementById("header-item-content-transfer").style.display = "none"
            document.getElementById("header-item-content-ok").style.display = "block"
            if (choose_callback_mode == "file") { // 选择文件
                neutron.setTitle("Choose File")
                disable_mulit_choose = true
                document.getElementById("header-item-content-ok").addEventListener("click", () => { // 确认
                    if (choose_files.size == 0) { // 未选择
                        return
                    }
                    if (files_lst[choose_files.values().next().value].isdir) { // 文件夹
                        return
                    }
                    var path_tmp = file_path // 处理path
                    if (path_tmp == "/") {
                        path_tmp = ""
                    }
                    path_tmp = path_tmp + "/" + files_lst[choose_files.values().next().value].name
                    neutron.sendMessageToWin(choose_callback_winid, { // 回调
                        "type": "choose_file",
                        "data": path_tmp,
                        "id": choose_callback_userid
                    }
                    )
                    neutron.close()
                })
            } else if (choose_callback_mode == "files") { // 选择多文件
                neutron.setTitle("Choose Files")
                disable_mulit_choose = false
                document.getElementById("header-item-content-ok").addEventListener("click", () => {
                    if (choose_files.size == 0) {
                        return
                    }
                    for (var i of choose_files) {
                        if (files_lst[i].isdir) {
                            return
                        }
                    }
                    var path_lst = []
                    for (var i of choose_files) {
                        var path_tmp = file_path
                        if (path_tmp == "/") {
                            path_tmp = ""
                        }
                        path_tmp = path_tmp + "/" + files_lst[i].name
                        path_lst.push(path_tmp)
                    }
                    neutron.sendMessageToWin(choose_callback_winid, {
                        "type": "choose_files",
                        "data": path_lst,
                        "id": choose_callback_userid
                    }
                    )
                    neutron.close()
                })
            } else if (choose_callback_mode == "dir") { // 选择目录
                neutron.setTitle("Choose Dir")
                disable_mulit_choose = true
                document.getElementById("header-item-content-ok").addEventListener("click", () => {
                    if (choose_files.size == 0) {
                        return
                    }
                    if (!files_lst[choose_files.values().next().value].isdir) {
                        return
                    }
                    var path_tmp = file_path
                    if (path_tmp == "/") {
                        path_tmp = ""
                    }
                    path_tmp = path_tmp + "/" + files_lst[choose_files.values().next().value].name
                    neutron.sendMessageToWin(choose_callback_winid, {
                        "type": "choose_dir",
                        "data": path_tmp,
                        "id": choose_callback_userid
                    }
                    )
                    neutron.close()
                })
            } else {
                neutron.close()
            }
        }
        if (loadobj != null) {
            // 存在会话
            file_path = loadobj.file_path;
            window.parent.NEUTRON_FILEMANAGER_CUTLIST = loadobj.cutfile_list;
            cutmode = loadobj.cutmode;
            show_hides = loadobj.show_hides;
            history_lst = loadobj.history_lst;
        }
        if (neutron.winid < 100000) {
            setInterval(() => {
                neutron.saveData(
                    {
                        "file_path": file_path,
                        "cutfile_list": window.parent.NEUTRON_FILEMANAGER_CUTLIST,
                        "cutmode": cutmode,
                        "show_hides": show_hides,
                        "history_lst": history_lst
                    }
                ) // 定时保存会话
            }, 5000);
        }
        load_files()
    })
}

function bind_all_events() { // 绑定所有事件
    document.getElementById("routebar").addEventListener("wheel", onscroll, { passive: true }); // 地址栏滚动
    document.getElementById("last_btn").addEventListener("click", load_history) // 返回上一个历史
    document.getElementById("back_btn").addEventListener("click", load_back) // 转到上级
    document.getElementById('routebar-input-input').addEventListener('blur', hide_path_input); // 地址栏隐藏
    document.getElementById('routebar-input-input').addEventListener('keyup', path_input_callback); // 地址栏输入(监听回车)
    document.getElementById('files').addEventListener("click", clean_choose_callback) // 取消选择
    document.getElementById('leftbar').addEventListener("click", clean_choose_callback) // 取消选择
    document.getElementById('header-item-content-new').addEventListener("click", btn_new_callback) // 新建菜单
    document.getElementById('new_file_menu_show_helper').addEventListener("click", new_btn_cancel_callback) // 覆盖层，用于关闭菜单
    document.getElementById("new_file_input_show_helper").addEventListener("click", new_file_input_cancel_callback) // 覆盖层，用于关闭输入框
    document.getElementById("header-item-content-rename").addEventListener("click", rename_callback) // 重命名按钮
    document.getElementById("header-item-content-cut").addEventListener("click", cut_callback) // 剪切按钮
    document.getElementById("header-item-content-copy").addEventListener("click", copy_callback) // 复制按钮
    document.getElementById("header-item-content-paste").addEventListener("click", paste_callback) // 粘贴按钮
    document.getElementById("header-item-content-remove").addEventListener("click", delete_callback) // 删除按钮
    document.body.addEventListener("keyup", shortcut_callback) // 快捷键
    document.getElementById("search-input").addEventListener("input", search_callback) // 实时搜索
    document.getElementById("header-item-content-transfer").addEventListener("click", download_callback) // 传输按钮
}

function dblclick_callback(obj_id_now) { // 文件打开事件
    if (choose_lock) {
        return
    }
    if (search_mode == true) {
        close_search()
    }
    if (file_path == "/") { // 处理根目录
        file_path = ""
    }
    if (files_lst[obj_id_now].name[0].charAt(0) == '/') {
        var open_file_abs_path = files_lst[obj_id_now].name
    } else {
        var open_file_abs_path = file_path + "/" + files_lst[obj_id_now].name
    }
    if (files_lst[obj_id_now].isdir) { // 文件夹
        file_path = open_file_abs_path
        load_files()
    } else { // 文件
        neutron.createIframeWin("Open File", PAGE_PATH + "/open.html#" + open_file_abs_path, 0, 0)
    }
}
function click_callback(e, obj_id_now) { // 文件选择事件
    if (choose_lock) {
        return
    }
    if (!disable_mulit_choose && choose_files.has(obj_id_now) && (multi_choose || e.ctrlKey)) { // 取消选择
        choose_files.delete(obj_id_now)
        document.getElementById("file-item-" + obj_id_now).classList.remove("file-item-choose")
    } else {
        if (disable_mulit_choose || !multi_choose && !e.ctrlKey) { // 非多选
            for (var i of choose_files) { // 取消选择
                document.getElementById("file-item-" + i).classList.remove("file-item-choose")
            }
            choose_files = new Set()
        }
        choose_files.add(obj_id_now) // 选择
        document.getElementById("file-item-" + obj_id_now).classList.add("file-item-choose")
    }
    e.stopPropagation();
}
function clean_choose_callback(e) { // 清除选择
    for (var i of choose_files) {
        document.getElementById("file-item-" + i).classList.remove("file-item-choose")
    }
    choose_files = new Set()

}
function create_file_dom_obj(icon_link, name, size) { // 新建文件 dom
    var template = `
    <div class="file-item" id="file-item-`+ (obj_id) + `" draggable="true" ondrop="file_drop(event,` + obj_id + `)" ondragover="file_dragover(event,` + obj_id + `)" oncontextmenu="file_right_click(event,` + obj_id + `)">
        <img width="16" height="16" data-click="false" data-flip="false" data-invert="false" data-rounded="false"
            src="`+ icon_link + `" alt="" draggable="false">
            <span class="file-item-name">`+ htmlEncode(name) + `</span>
            <span class="file-item-size">`+ size + `</span>
    </div>`
    document.getElementById("files").insertAdjacentHTML('beforeend', template);
    (function (obj_id_now) {
        // 设置回调
        setTimeout(() => {
            document.getElementById("file-item-" + obj_id_now).addEventListener("dblclick", function () {
                dblclick_callback(obj_id_now)
            })
            document.getElementById("file-item-" + obj_id_now).addEventListener("click", function (e) {
                click_callback(e, obj_id_now)
            })
            document.getElementById("file-item-" + obj_id_now).addEventListener("dragstart", function (e) {
                // e.preventDefault();
                if (!choose_files.has(obj_id_now)) {
                    for (var i of choose_files) { // 取消选择
                        document.getElementById("file-item-" + i).classList.remove("file-item-choose")
                    }
                    choose_files = new Set()
                    document.getElementById("file-item-" + obj_id_now).classList.add("file-item-choose")
                    choose_files.add(obj_id_now) // 选择
                }
                if (choose_files.size == 1) {
                    file_real_path = file_path
                    if (file_path == "/") {
                        file_real_path = ""
                    }
                    file_real_path = file_real_path + "/" + files_lst[obj_id_now].name
                    e.dataTransfer.setData("text/plain", file_real_path);
                }
                e.dataTransfer.setData("application/neutron-file-transfer", JSON.stringify({
                    "from": file_path,
                    "filelist": Array.from(choose_files).map(index => files_lst[index])
                }));
                e.dataTransfer.setDragImage(document.getElementById("move_show_helper"), 32, 32);
                e.dataTransfer.effectAllowed = "copyMove";
                e.dataTransfer.dropEffect = "move"
            })
        }, 50)
    })(obj_id++)
}
function create_files_dom(files_array) { // 遍历文件
    obj_id = 0
    choose_files = new Set()
    document.getElementById("files").innerHTML = ""
    for (var i = 0; i < files_array.length; i++) {
        create_file_dom_obj(STATIC_PATH + "/img/" + files_array[i]["img"], files_array[i]["name"], files_array[i]["size"])
    }
}
function load_files(push_history = true) { // 加载文件夹
    console.log("Into path: " + file_path)
    var xhr = new XMLHttpRequest()
    xhr.open("GET", API_PATH + "/files?path=" + file_path + "&show_hides=" + show_hides, true);
    choose_lock = true
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
            choose_lock = false
        }
        if (xhr.readyState == 4 && xhr.status == 200) {
            var files = JSON.parse(xhr.responseText)
            if (files["code"] == 1) { // 显示错误信息
                document.getElementById("files").innerHTML = ""
                alert(files["msg"])
            } else {
                load_path_list()
                if (push_history) {
                    history_lst.push(file_path)
                }
                create_files_dom(files["data"])
                files_lst = files["data"]
                load_watch_ws()
            }
        }
    }
    xhr.send()
}
function load_watch_ws() { // 监控文件变化
    if (file_path_ws_tmp == file_path) {
        return
    }
    file_path_ws_tmp = file_path
    if (watch_ws != null && watch_ws.readyState == 1) {
        watch_ws.close()
    }
    setTimeout(() => {
        watch_ws = new WebSocket(API_PATH + "/watch?path=" + file_path)
        watch_ws.onmessage = function (e) {
            load_files(false)
        }
    }, 30)
}
function load_history() { // 加载上一个文件夹
    if (search_mode == true) {
        close_search()
    }
    if (choose_lock) {
        return
    }
    if (history_lst.length > 1) {
        history_lst.splice(history_lst.length - 1, 1)
        file_path = history_lst[history_lst.length - 1]
        history_lst.splice(history_lst.length - 1, 1)
        load_files()
    }
}
function load_back() { // 加载上一级
    if (search_mode == true) {
        close_search()
    }
    if (choose_lock) {
        return
    }
    if (file_path != "/") { // 目录计算
        file_path = file_path.substring(0, file_path.lastIndexOf("/"))
        if (file_path == "") {
            file_path = "/"
        }
        load_files()
    }
}
function hide_path_input() { // 输入地址栏
    document.getElementById("routebar-input").style.display = "none";
}
function show_path_input() { // 输入地址栏
    document.getElementById("routebar-input-input").value = file_path
    document.getElementById("routebar-input").style.display = "block"; document.getElementById('routebar-input-input').focus()
}
function load_path_list() { // 加载路径栏
    var template = `
        <div class="routebar-routebox" id="routebar-routebox-id--1">
            <div class="routebar-routebox-text"><span>[root]</span></div>
        </div>`
    function bind_event(ids, paths) {
        setTimeout(() => {
            document.getElementById("routebar-routebox-id-" + ids).addEventListener("click", function () {
                if (search_mode == true) {
                    close_search()
                }
                if (file_path != paths) {
                    file_path = paths
                    load_files()
                } else {
                    show_path_input()
                }
            })
        }, 50)
    }
    document.getElementById("routebar").innerHTML = template;
    bind_event(-1, "/") // 设置[root]按钮
    var base_str = ""
    if (file_path != "/") {
        for (var i = 1; i < file_path.split("/").length; i++) {
            template = `
            <div class="routebar-routebox" id="routebar-routebox-id-`+ i + `">
                <div class="routebar-routebox-split"><span>/</span></div>
                <div class="routebar-routebox-text"><span>`+ file_path.split("/")[i].replace(" ", "&nbsp;"); + `</span></div>
            </div>`
            document.getElementById("routebar").insertAdjacentHTML('beforeend', template);
            base_str = base_str + "/" + file_path.split("/")[i]
            bind_event(i, base_str)
        }
    }
}
function path_input_callback(event) { // 地址栏回车
    if (search_mode == true) {
        close_search()
    }
    if (choose_lock) {
        return
    }
    event.preventDefault()
    if (event.keyCode == 13) { // 回车
        hide_path_input() // 隐藏输入框
        var new_file_path = document.getElementById("routebar-input-input").value
        if (new_file_path != "" && file_path != new_file_path) { // 输入了新目录
            // 计算目录
            if (new_file_path[0] != "/") { // 添加为绝对路径
                new_file_path = "/" + new_file_path
            }
            if (new_file_path[new_file_path.length - 1] == "/") { // 删掉末尾斜杠
                new_file_path = new_file_path.substring(0, new_file_path.length - 1)
            }
            if (new_file_path == "") { // 根目录特殊处理
                new_file_path = "/"
            }
            file_path = new_file_path
            load_files()
        }
    }
}
function btn_new_callback() { // 新建回调
    if (search_mode == true) {
        close_search()
    }
    if (choose_lock) {
        return
    }
    document.getElementById("new_file_menu").style.display = "block" // 显示
    document.getElementById("new_file_menu_show_helper").style.display = "block"
    setTimeout(() => {
        document.getElementById("new_file_menu").style.height = "80px" // 动画
    }, 0)
}
function new_btn_cancel_callback() {
    if (choose_lock) {
        return
    }
    setTimeout(() => { // 动画
        document.getElementById("new_file_menu").style.height = "0px"
    }, 0)
    setTimeout(() => {
        document.getElementById("new_file_menu").style.display = "none"
        document.getElementById("new_file_menu_show_helper").style.display = "none"
    }, 100)
}
function create_file_callback() { // 新建文件
    if (search_mode == true) {
        close_search()
        load_files(false)
        return
    }
    if (choose_lock) {
        return
    }
    new_btn_cancel_callback()
    document.getElementById("new_file_input_show_helper").style.display = "block"
    document.getElementById("files").scrollTo(0, 0)
    // 输入框
    var template = `
    <div class="file-item" id="file-item-new">
        <img width="16" height="16" data-click="false" data-flip="false" data-invert="false" data-rounded="false"
            src="`+ STATIC_PATH + `/img/icons/default_file.svg" alt="" draggable="false">
            <input class="file-item-name" id="file-item-new-input">
    </div>`
    // 取消选择
    for (var i of choose_files) {
        document.getElementById("file-item-" + i).classList.remove("file-item-choose")
    }
    choose_files = new Set()
    document.getElementById("files").insertAdjacentHTML('afterbegin', template);
    create_type = "file"
    setTimeout(() => { // 添加输入框事件
        document.getElementById("file-item-new-input").focus()
        document.getElementById('file-item-new-input').addEventListener('keyup', new_input_callback);
    }, 0)
    create_is_rename = ""
}
function create_dir_callback() { // 创建目录
    if (choose_lock) {
        return
    }
    new_btn_cancel_callback()
    document.getElementById("new_file_input_show_helper").style.display = "block"
    document.getElementById("files").scrollTo(0, 0) // 滚动
    var template = `
    <div class="file-item" id="file-item-new">
        <img width="16" height="16" data-click="false" data-flip="false" data-invert="false" data-rounded="false"
            src="`+ STATIC_PATH + `/img/icons/default_folder.svg" alt="" draggable="false">
            <input class="file-item-name" id="file-item-new-input">
    </div>`
    for (var i of choose_files) {
        document.getElementById("file-item-" + i).classList.remove("file-item-choose")
    }
    choose_files = new Set()
    document.getElementById("files").insertAdjacentHTML('afterbegin', template);
    create_type = "dir"
    setTimeout(() => {
        document.getElementById("file-item-new-input").focus()
        document.getElementById('file-item-new-input').addEventListener('keyup', new_input_callback);
    }, 0)
    create_is_rename = ""
}
function new_file_input_cancel_callback() { // 新建文件回调
    document.getElementById("new_file_input_show_helper").style.display = "none"
    var input_text = document.getElementById("file-item-new-input").value
    setTimeout(() => {
        document.getElementById("file-item-new").outerHTML = ""
    }, 10)
    if (input_text == create_is_rename) {
        if (create_is_rename != "")
            document.getElementById("file-item-" + choosed_file_id).style.display = "block"
        return
    }

    if ((/[`&|/\\;*?#^%$'"]/.test(input_text))) { // 检查文件名
        setTimeout(() => {
            alert("文件名不合法")
        }, 0)
        return
    }
    var xhr = new XMLHttpRequest();
    if (create_is_rename == "") { // 重命名复用
        var url = API_PATH + '/new/' + create_type + "?path=" + encodeURI(file_path + "/" + input_text)
    } else {
        var url = API_PATH + "/rename?from_name=" + encodeURI(create_is_rename) + "&to_name=" + encodeURI(input_text) + "&path=" + encodeURI(file_path)
    }
    choose_lock = true
    xhr.open('POST', url, true);
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
            choose_lock = false
        }
        if (xhr.readyState == 4 && xhr.status == 200) {
            var new_file_path = JSON.parse(xhr.responseText)
            if (new_file_path.code == 1) {
                if (create_is_rename != "")
                    document.getElementById("file-item-" + choosed_file_id).style.display = "block"
                alert(new_file_path.msg);
            } else {
                load_files(false)
            }
        }
    }
    xhr.send();
}
function new_input_callback(event) { // 新建文件回调
    event.preventDefault()
    if (event.keyCode == 13) {
        new_file_input_cancel_callback()
    }
}
function rename_callback() { // 重命名按钮
    if (choose_lock) {
        return
    }

    if (choose_files.size != 1) { // 选择单个文件
        return
    }

    document.getElementById("new_file_input_show_helper").style.display = "block"

    create_is_rename = (files_lst[[...choose_files][0]]["name"]) // 原先文件名
    choosed_file_id = [...choose_files][0] // 记录当前选中的文件id

    document.getElementById("file-item-" + [...choose_files][0]).style.display = "none"
    var template = `
    <div class="file-item" id="file-item-new">
        <img width="16" height="16" data-click="false" data-flip="false" data-invert="false" data-rounded="false"
            src="`+ STATIC_PATH + "/img/" + files_lst[[...choose_files][0]]["img"] + `" alt="" draggable="false">
            <input class="file-item-name" id="file-item-new-input" value="`+ htmlEncode(create_is_rename) + `">
    </div>`
    for (var i of choose_files) {
        document.getElementById("file-item-" + i).classList.remove("file-item-choose")
    }
    choose_files = new Set()
    document.getElementById("file-item-" + choosed_file_id).insertAdjacentHTML('beforebegin', template);
    document.getElementById("files").scrollTo({
        top: document.getElementById("file-item-" + i).offsetTop // 滚动到文件位置
    })
    create_type = "dir"
    setTimeout(() => {
        document.getElementById("file-item-new-input").focus()
        document.getElementById('file-item-new-input').addEventListener('keyup', new_input_callback);
    }, 0)
}
function cut_callback() { // 剪切
    window.parent.NEUTRON_FILEMANAGER_CUTLIST = []
    for (var i of choose_files) {
        var file_path_tmp = file_path // 操作路径
        if (file_path_tmp == "/") {
            file_path_tmp = ""
        }
        window.parent.NEUTRON_FILEMANAGER_CUTLIST.push(file_path_tmp + "/" + files_lst[i]["name"])
    }
    cutmode = "move"
    console.log("Cut file")

    // 取消选择
    for (var i of choose_files) {
        document.getElementById("file-item-" + i).classList.remove("file-item-choose")
    }
    choose_files = new Set()
}
function copy_callback() { // 复制
    window.parent.NEUTRON_FILEMANAGER_CUTLIST = []
    for (var i of choose_files) {
        var file_path_tmp = file_path
        if (file_path_tmp == "/") {
            file_path_tmp = ""
        }
        window.parent.NEUTRON_FILEMANAGER_CUTLIST.push(file_path_tmp + "/" + files_lst[i]["name"])
    }
    cutmode = "copy"
    console.log("Copy file")
    for (var i of choose_files) {
        document.getElementById("file-item-" + i).classList.remove("file-item-choose")
    }
    choose_files = new Set()
}
function paste_callback() { // 粘贴
    if (search_mode == true) {
        close_search()
        load_files(false)
        return
    }
    if (choose_lock) {
        return
    }
    console.log("Paste file")
    for (var i of choose_files) {
        document.getElementById("file-item-" + i).classList.remove("file-item-choose")
    }
    choose_files = new Set()
    var xhr = new XMLHttpRequest();
    var url = API_PATH + "/paste"
    choose_lock = true
    xhr.open('POST', url, true);
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
            choose_lock = false
        }
        if (xhr.readyState == 4 && xhr.status == 200) { // 更新
            var new_file_path = JSON.parse(xhr.responseText)
            if (new_file_path.code == 1) {
                alert(new_file_path.msg);
            } else {
                load_files(false)
            }
            window.parent.NEUTRON_FILEMANAGER_CUTLIST = []
        }
    }
    xhr.send(JSON.stringify({
        "types": cutmode,
        "origin": window.parent.NEUTRON_FILEMANAGER_CUTLIST,
        "dist": file_path
    }))
    if (window.parent.window.NEUTRON_TASKS_OPENED != true) { // 如果没有打开任务面板
        neutron.createIframeWin("Tasks", "/api/plugin/tasks/iframe/index.html")
    }
}
function shortcut_callback(e) { // 快捷键
    e.preventDefault()
    if ((e.metaKey || e.ctrlKey) && e.key == "c") {
        // C-C 复制
        copy_callback()
    } else if ((e.metaKey || e.ctrlKey) && e.key == "x") {
        // C-X 剪切
        cut_callback()
    } else if ((e.metaKey || e.ctrlKey) && e.key == "v") {
        // C-V 粘贴
        paste_callback()
    } else if (e.key == "F2") {
        // F2  重命名
        rename_callback()
    } else if ((e.metaKey || e.ctrlKey) && e.key == "a") {
        // C-A 全选
        for (var i of choose_files) {
            document.getElementById("file-item-" + i).classList.remove("file-item-choose")
        }
        choose_files = new Set()
        for (var i = 0; i < files_lst.length; i++) {
            choose_files.add(i)
            document.getElementById("file-item-" + i).classList.add("file-item-choose")
        }
    } else if (e.key == "Delete") {
        // Delete 删除
        delete_callback()
    }
}
function delete_callback() { // 删除
    if (choose_lock) {
        return
    }
    if (choose_files.size == 0) { // 是否选择
        return
    }
    var rmfile_list = [] // 生成删除列表
    for (var i of choose_files) {
        var file_path_tmp = file_path // 操作路径
        if (file_path_tmp == "/") {
            file_path_tmp = ""
        }
        rmfile_list.push(file_path_tmp + "/" + files_lst[i]["name"])
    }
    for (var i of choose_files) { // 取消选择
        document.getElementById("file-item-" + i).classList.remove("file-item-choose")
    }
    choose_files = new Set()

    // 发送请求
    var xhr = new XMLHttpRequest();
    console.log("Delete file")
    var url = API_PATH + "/remove"
    choose_lock = true
    window.parent.NEUTRON_FILEMANAGER_CUTLIST = []
    xhr.open('POST', url, true);
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
            choose_lock = false
        }
        if (xhr.readyState == 4 && xhr.status == 200) {
            var new_file_path = JSON.parse(xhr.responseText)
            if (new_file_path.code == 1) {
                alert(new_file_path.msg);
            } else {
                load_files(false)
            }
            window.parent.NEUTRON_FILEMANAGER_CUTLIST = []
        }
    }
    xhr.send(JSON.stringify({
        "origin": rmfile_list,
        "types": "delete"
    }))

    if (window.parent.window.NEUTRON_TASKS_OPENED != true) { // 如果没有打开任务面板
        neutron.createIframeWin("Tasks", "/api/plugin/tasks/iframe/index.html")
    }
}
function close_search() { // 取消搜索
    document.getElementById("fileinfo").innerText = ""
    search_mode = false
    document.getElementById("search-input").value = ""
    if (ws != null) {
        ws.close()
    }
}
function search_callback() { // 搜索
    console.log("Search call")
    if (search_mode == false && document.getElementById("search-input").value.length > 0) {
        console.log("Search file")
        search_mode = true
        create_files_dom([]) // 清空
        ws = new WebSocket(API_PATH + "/search?search_path=" + file_path)
        document.getElementById("fileinfo").innerText = "搜索中"
        ws.onmessage = function (event) {
            if (search_mode == false) {
                return
            }
            var data = JSON.parse(event.data)
            if (data.type == "result") { // 搜索结果
                if (data["data"]["retcode"] != 0) {
                    if (data["data"]["retcode"] == 1) {
                        document.getElementById("fileinfo").innerText = "找不到文件"
                    } else if (data["data"]["retcode"] > 64) {
                        document.getElementById("fileinfo").innerText = "请先安装 plocate"
                    } else {
                        document.getElementById("fileinfo").innerText = "未知错误\nplocate 返回代码：" + data["data"]["retcode"]
                    }
                } else {
                    document.getElementById("fileinfo").innerText = ""
                }
                files_lst = data["data"]["data"]
                create_files_dom(data["data"]["data"])
            } else if (data.type == "db_created") {
                if (data["data"]["data"] == 1) {
                    document.getElementById("fileinfo").innerText = "数据库建立失败"
                } else if (data["data"]["data"] > 64) {
                    document.getElementById("fileinfo").innerText = "请先安装 plocate"
                } else if (data["data"]["data"] != 0) {
                    document.getElementById("fileinfo").innerText = "未知错误\nupdatedb 返回代码：" + data["data"]["data"]
                }
            }
        }
        ws.onopen = function () { // 连接成功
            if (document.getElementById("search-input").value == "") {
                return
            }
            ws.send(JSON.stringify({
                "type": "search",
                "data": document.getElementById("search-input").value
            }))
        }
    } else if (search_mode == true && document.getElementById("search-input").value.length == 0) {
        close_search() // 关闭搜索
        load_files(false)
        return
    }
    if (search_mode == true) { // 更新搜索
        if (ws != null && ws.readyState != 1) {
            return
        }
        ws.send(JSON.stringify({
            "type": "search",
            "data": document.getElementById("search-input").value
        }))
    }
}

function load_bookmarks() { // 加载书签
    document.getElementById("bar_links_group").innerHTML = ""
    html_list = ""
    for (var i = 0; i < bookmark_list.length; i++) {
        var template = `<div class="bar_link" id="bar-link-` + i + `" oncontextmenu="leftbar_contextmenu(event,` + i + `)"><span>` + bookmark_list[i]["text"] + `</span></div>`
        html_list += template
    }
    setTimeout(() => {
        document.getElementById("bar_links_group").innerHTML = html_list
        setTimeout(() => {
            for (var i = 0; i < bookmark_list.length; i++) { // 遍历
                (function (elem_id) {
                    document.getElementById("bar-link-" + i).addEventListener("click", function () { // 选择事件
                        var bookmark_last_choice_tmp = bookmark_last_choice
                        if (bookmark_last_choice != -1) {
                            bookmark_last_choice = -1
                            unchoose_bookmark()
                        }
                        if (bookmark_last_choice_tmp != elem_id) {
                            bookmark_last_choice = elem_id
                            choose_bookmark()
                        }
                    })
                    document.getElementById("bar-link-" + i).addEventListener("dblclick", function () { // 双击事件
                        bookmark_last_choice = -1
                        unchoose_bookmark()
                        file_path = bookmark_list[elem_id]["path"]
                        load_files()
                    })
                })(i)
            }
        }, 0)
    }, 10)
}
function get_bookmark_text(path_str) { // 计算书签文本
    if (path_str == "/") {
        return "[root]"
    } else {
        return path_str.split("/").pop()
    }
}
function add_bookmark() { // 添加书签
    if (choose_files.size > 1) {
        return
    }
    bookmark_last_choice = -1
    unchoose_bookmark()
    if (choose_files.size == 0) {
        add_path = file_path
    } else {
        add_path = file_path
        if (file_path == "/") {
            add_path = ""
        }
        add_path = add_path + "/" + files_lst[choose_files.values().next().value]["name"]
        if (!files_lst[choose_files.values().next().value]["isdir"]) {
            return
        }
    }
    console.log("Add bookmark: " + add_path)
    bookmark_list.push({
        "text": get_bookmark_text(add_path),
        "path": add_path
    })
    load_bookmarks()
    sync_bookmark()
}
function remove_bookmark() { // 删除书签
    if (bookmark_last_choice == -1) {
        return
    }
    console.log("Remove bookmark: " + bookmark_list[bookmark_last_choice]["path"])
    bookmark_list.splice(bookmark_last_choice, 1)
    bookmark_last_choice = -1
    unchoose_bookmark()
    load_bookmarks()
    sync_bookmark()
}
function choose_bookmark() { // 选择书签状态
    if (bookmark_last_choice == -1) {
        return
    }
    document.getElementById("bar-link-" + bookmark_last_choice).classList.add("bar-link-choose")
}
function unchoose_bookmark() { // 取消选择书签状态
    var bookmark_choose_get = document.getElementsByClassName("bar-link-choose")
    if (bookmark_choose_get.length == 0) {
        return
    }
    bookmark_choose_get[0].classList.remove("bar-link-choose")
}
function sync_bookmark() { // 同步书签
    var xhr = new XMLHttpRequest();
    xhr.open("POST", API_PATH + "/bookmark", true);
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4 && xhr.status == 200) {
            var json = JSON.parse(xhr.responseText);
            if (json.code != 0) {
                alert(json.msg)
            }
        }
    }
    var data = JSON.stringify({
        "type": "sync",
        "data": bookmark_list
    })
    xhr.send(data);
}
function init_bookmarks() { // 加载书签
    var xhr = new XMLHttpRequest();
    xhr.open("GET", API_PATH + "/bookmark", true);
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4 && xhr.status == 200) {
            var json = JSON.parse(xhr.responseText);
            if (json.code != 0) {
                alert(json.msg)
                return
            }
            bookmark_list = json.data
            load_bookmarks()
        }
    }
    xhr.send();
}
function downloadFile(url, fileName) { // 下载文件
    console.log("Download: " + fileName)
    const link = document.createElement('a');
    link.href = url;
    link.download = fileName;
    link.target = "_blank";
    link.click();
}
function download_callback() { // 点击下载事件
    if (choose_files.size == 0) {
        setTimeout(() => {
            neutron.createIframeWin("File Upload", PAGE_PATH + "/upload.html#" + file_path, 0, 0)
        }, 10)
        return
    }
    var choose_files_mirror = new Set(Array.from(choose_files));
    for (var i of choose_files) { // 取消选择
        document.getElementById("file-item-" + i).classList.remove("file-item-choose")
    }
    choose_files = new Set()
    for (var i of choose_files_mirror.keys()) {
        if (files_lst[i]["isdir"]) {
            continue
        }
        var file_name = files_lst[i]["name"]
        var now_file_path = file_path
        if (now_file_path == "/") {
            now_file_path = ""
        }
        now_file_path = now_file_path + "/" + file_name
        downloadFile(API_PATH + "/download/" + file_name + "?path=" + now_file_path, file_name)
    }
}

function contains(list, value) { // 判断列表中是否包含某个值
    for (var i = 0; i < list.length; ++i) {
        if (list[i] === value) return true;
    }
    return false;
}

function file_dragover(e, obj_id) { // 拖拽文件进入
    if (!contains(e.dataTransfer.types, "application/neutron-file-transfer")) {
        return
    }
    e.preventDefault()
    e.stopPropagation()
}


function file_drop(e, obj_id) { // 放下文件
    if (!contains(e.dataTransfer.types, "application/neutron-file-transfer")) {
        return
    }
    var datas = JSON.parse(e.dataTransfer.getData("application/neutron-file-transfer"))
    if (datas.from == file_path) {
        return
    }
    e.preventDefault()
    e.stopPropagation()
    now_effect = (e.dataTransfer.dropEffect)
    if (now_effect == "none") { // 类型
        now_effect = "move"
    }
    if (e.ctrlKey) {
        now_effect = "copy"
    }
    if (e.shiftKey) {
        now_effect = "move"
    }
    if (datas["from"] == "/") {
        var file_path_tmp = ""
    } else {
        var file_path_tmp = datas["from"] // 源文件路径
    }
    var origin_lst = datas["filelist"].map(index => file_path_tmp + "/" + index["name"])
    var xhr = new XMLHttpRequest() // 粘贴
    var url = API_PATH + "/paste"
    choose_lock = true
    xhr.open('POST', url, true);
    xhr.setRequestHeader("Content-Type", "application/json");
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4) {
            choose_lock = false
        }
        if (xhr.readyState == 4 && xhr.status == 200) {
            var new_file_path = JSON.parse(xhr.responseText)
            if (new_file_path.code == 1) {
                alert(new_file_path.msg);
            } else {
                load_files(false)
            }
        }
    }
    xhr.send(JSON.stringify({
        "types": now_effect,
        "origin": origin_lst,
        "dist": file_path
    }))
    if (window.parent.window.NEUTRON_TASKS_OPENED != true) { // 如果没有打开任务面板
        neutron.createIframeWin("Tasks", "/api/plugin/tasks/iframe/index.html")
    }
}

function text_rewrite(text) { // 生成命令的转义
    var add_space = text.includes(" ")
    if (text.includes("@") || text.includes("$") || text.includes("#")) {
        add_space = true
    }
    text = text.replace(/\$/g, "\\$")
    if (add_space) {
        text = '"' + text + '"'
    }
    return text
}


function file_right_click(e, obj_id) { // 右键菜单
    e.preventDefault()
    e.stopPropagation()
    if (obj_id != -1 && !choose_files.has(obj_id)) {
        for (var i of choose_files) { // 取消选择
            document.getElementById("file-item-" + i).classList.remove("file-item-choose")
        }
        choose_files = new Set()
        document.getElementById("file-item-" + obj_id).classList.add("file-item-choose")
        choose_files.add(obj_id) // 选择
    }
    if (obj_id == -1) {
        var action_list = [
            {
                "name": "粘贴",
                "func": function () {
                    if (window.parent.window.NEUTRON_FILEMANAGER_CUTLIST.length == 0) {
                        return
                    }
                    paste_callback()
                }
            },
            {
                "name": "在终端中打开",
                "func": function () {
                    var params = new URLSearchParams();
                    params.append('cmd', "cd " + text_rewrite(file_path));
                    neutron.createIframeWin("Terminal", "/api/plugin/terminal/iframe/index.html?" + params.toString())
                }
            },
            {
                "name": "复制路径",
                "func": function () {
                    var fp = file_path

                    navigator.clipboard.writeText(fp).then(() => { }, () => {
                        var aux = document.createElement("input");
                        aux.setAttribute("value", fp);
                        document.body.appendChild(aux);
                        aux.select();
                        document.execCommand("copy");
                        document.body.removeChild(aux);
                    });
                }
            },
            {
                "name": "刷新",
                "func": function () {
                    load_files(false)
                }
            },
            {
                "name": "新建",
                "func": function () {
                    var new_action_list = [
                        {
                            "name": "文件",
                            "func": function () {
                                create_file_callback()
                            }
                        }, {
                            "name": "文件夹",
                            "func": function () {
                                create_dir_callback()
                            }
                        }
                    ]
                    neutron.showContextMenu((ret) => {
                        new_action_list[ret[0]]["func"]()
                    }, new_action_list.map((index) => index["name"]))
                }
            },
            {
                "name": "属性",
                "func": function () {
                    var params = new URLSearchParams()
                    params.append('path', file_path)
                    neutron.createIframeWin("Attribute", PAGE_PATH + "/attribute.html?" + params.toString())
                }
            }
        ]
    } else {
        var action_list = [
            {
                "name": "打开",
                "func": function () {
                    dblclick_callback(obj_id)
                }
            },
            {
                "name": "重命名",
                "func": function () {
                    for (var i of choose_files) { // 取消选择
                        document.getElementById("file-item-" + i).classList.remove("file-item-choose")
                    }
                    choose_files = new Set()
                    document.getElementById("file-item-" + obj_id).classList.add("file-item-choose")
                    choose_files.add(obj_id) // 选择
                    rename_callback()
                }
            },
            {
                "name": "复制",
                "func": function () {
                    copy_callback()
                }
            },
            {
                "name": "剪切",
                "func": function () {
                    cut_callback()
                }
            },
            {
                "name": "粘贴",
                "func": function () {
                    if (window.parent.window.NEUTRON_FILEMANAGER_CUTLIST.length == 0) {
                        return
                    }
                    paste_callback()
                }
            },
            {
                "name": "在终端中打开",
                "func": function () {
                    var params = new URLSearchParams();
                    params.append('cmd', "cd " + text_rewrite(file_path));
                    neutron.createIframeWin("Terminal", "/api/plugin/terminal/iframe/index.html?" + params.toString())
                }
            },
            {
                "name": "复制路径",
                "func": function () {
                    var fp = file_path
                    if (fp == "/") {
                        fp = ""
                    }
                    fp = fp + "/" + files_lst[obj_id]["name"]

                    navigator.clipboard.writeText(fp).then(() => { }, () => {
                        // 兼容方案
                        var aux = document.createElement("input");
                        aux.setAttribute("value", fp);
                        document.body.appendChild(aux);
                        aux.select();
                        document.execCommand("copy");
                        document.body.removeChild(aux);
                    });
                }
            },
            {
                "name": "刷新",
                "func": function () {
                    load_files(false)
                }
            },
            {
                "name": "属性",
                "func": function () {
                    for (var i of choose_files) { // 取消选择
                        document.getElementById("file-item-" + i).classList.remove("file-item-choose")
                    }
                    choose_files = new Set()
                    document.getElementById("file-item-" + obj_id).classList.add("file-item-choose")
                    choose_files.add(obj_id) // 选择
                    var fp = file_path
                    if (fp == "/") {
                        fp = ""
                    }
                    fp = fp + "/" + files_lst[obj_id]["name"]
                    var params = new URLSearchParams()
                    params.append('path', fp)
                    neutron.createIframeWin("Attribute", PAGE_PATH + "/attribute.html?" + params.toString())
                }
            }
        ]
    }
    neutron.showContextMenu((ret) => {
        action_list[ret[0]]["func"]()
    }, action_list.map((index) => index["name"]))
}

function leftbar_contextmenu(event, id) { // 书签栏右键菜单
    event.preventDefault()
    event.stopPropagation()
    unchoose_bookmark()
    bookmark_last_choice = id
    choose_bookmark()

    var action_list = [
        {
            "name": "添加书签",
            "func": add_bookmark
        },
        {
            "name": "移除书签",
            "func": remove_bookmark
        }
    ]
    neutron.showContextMenu((ret) => {
        action_list[ret[0]]["func"]()
    }, action_list.map((index) => index["name"]))
}
